home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / sbin / savelog < prev    next >
Text File  |  2006-04-25  |  8KB  |  302 lines

  1. #! /bin/sh
  2. # savelog - save a log file
  3. #    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  4. #    Copyright (C) 1992  Ronald S. Karr
  5. # Slight modifications by Ian A. Murdock <imurdock@gnu.ai.mit.edu>:
  6. #    * uses `gzip' rather than `compress'
  7. #    * doesn't use $savedir; keeps saved log files in the same directory
  8. #    * reports successful rotation of log files
  9. #    * for the sake of consistency, files are rotated even if they are
  10. #      empty
  11. # More modifications by Guy Maor <maor@debian.org>:
  12. #       * cleanup.
  13. #       * -p (preserve) option
  14. # usage: savelog [-m mode] [-u user] [-g group] [-t] [-p] [-c cycle]
  15. #         [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file...
  16. #    -m mode      - chmod log files to mode
  17. #    -u user      - chown log files to user
  18. #    -g group  - chgrp log files to group
  19. #    -c cycle  - save cycle versions of the logfile    (default: 7)
  20. #    -r rolldir- use rolldir instead of . to roll files
  21. #    -C      - force cleanup of cycled logfiles
  22. #    -d      - use standard date for rolling
  23. #    -t      - touch file
  24. #    -l      - don't compress any log files    (default: compress)
  25. #       -p        - preserve mode/user/group of original file
  26. #    -j        - use bzip2 instead of gzip
  27. #    -n      - do not rotate empty files
  28. #    -q      - be quiet
  29. #    file       - log file names
  30. #
  31. # The savelog command saves and optionally compresses old copies of files.
  32. # Older version of 'file' are named:
  33. #
  34. #        'file'.<number><compress_suffix>
  35. #
  36. # where <number> is the version number, 0 being the newest.  By default,
  37. # version numbers > 0 are compressed (unless -l prevents it). The
  38. # version number 0 is never compressed on the off chance that a process
  39. # still has 'file' opened for I/O.
  40. #
  41. # if the '-d' option is specified, <number> will be YYMMDDhhmmss
  42. #
  43. # If the 'file' does not exist and -t was given, it will be created.
  44. #
  45. # For files that do exist and have lengths greater than zero, the following 
  46. # actions are performed.
  47. #
  48. #    1) Version numered files are cycled.  That is version 6 is moved to
  49. #       version 7, version is moved to becomes version 6, ... and finally
  50. #       version 0 is moved to version 1.  Both compressed names and
  51. #       uncompressed names are cycled, regardless of -t.  Missing version 
  52. #       files are ignored.
  53. #
  54. #    2) The new file.1 is compressed and is changed subject to 
  55. #       the -m, -u and -g flags.  This step is skipped if the -t flag 
  56. #       was given.
  57. #
  58. #    3) The main file is moved to file.0.
  59. #
  60. #    4) If the -m, -u, -g, -t, or -p flags are given, then the file is
  61. #          touched into existence subject to the given flags.  The -p flag
  62. #          will preserve the original owner, group, and permissions.
  63. #
  64. #    5) The new file.0 is changed subject to the -m, -u and -g flags.
  65. #
  66. # Note: If no -m, -u, -g, -t, or -p is given, then the primary log file is 
  67. #    not created.
  68. #
  69. # Note: Since the version numbers start with 0, version number <cycle>
  70. #       is never formed.  The <cycle> count must be at least 2.
  71. #
  72. # Bugs: If a process is still writing to the file.0 and savelog
  73. #    moved it to file.1 and compresses it, data could be lost.
  74. #    Smail does not have this problem in general because it
  75. #    restats files often.
  76.  
  77. # common location
  78. export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin
  79. COMPRESS="gzip -9f"
  80. DOT_Z=".gz"
  81. DATUM=`date +%Y%m%d%H%M%S`
  82.  
  83. # parse args
  84. exitcode=0    # no problems to far
  85. prog=`basename $0`
  86. mode=
  87. user=
  88. group=
  89. touch=
  90. forceclean=
  91. rolldir=
  92. datum=
  93. preserve=
  94. quiet=0
  95. rotateifempty=yes
  96. count=7
  97.  
  98. usage()
  99. {
  100.     echo "Usage: $prog [-m mode] [-u user] [-g group] [-t] [-c cycle] [-p]"
  101.     echo "             [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file ..."
  102.     echo "    -m mode       - chmod log files to mode"
  103.     echo "    -u user       - chown log files to user"
  104.     echo "    -g group   - chgrp log files to group"
  105.     echo "    -c cycle   - save cycle versions of the logfile (default: 7)"
  106.     echo "    -r rolldir - use rolldir instead of . to roll files"
  107.     echo "    -C       - force cleanup of cycled logfiles"
  108.     echo "    -d       - use standard date for rolling"
  109.     echo "    -t       - touch file"
  110.     echo "    -l       - don't compress any log files (default: compress)"
  111.     echo "    -p         - preserve mode/user/group of original file"
  112.     echo "    -j         - use bzip2 instead of gzip"
  113.     echo "    -n         - do not rotate empty files"
  114.     echo "    -q         - suppress rotation message"
  115.     echo "    file        - log file names"
  116. }
  117.  
  118.  
  119. fixfile()
  120. {
  121.     if [ -n "$user" ]; then
  122.     chown -- "$user" "$1"
  123.     fi
  124.     if [ -n "$group" ]; then 
  125.     chgrp -- "$group" "$1"
  126.     fi
  127.     if [ -n "$mode" ]; then 
  128.     chmod -- "$mode" "$1"
  129.     fi
  130. }
  131.  
  132.  
  133. while getopts m:u:g:c:r:Cdtlphjnq opt ; do
  134.     case "$opt" in
  135.     m) mode="$OPTARG" ;;
  136.     u) user="$OPTARG" ;;
  137.     g) group="$OPTARG" ;;
  138.     c) count="$OPTARG" ;;
  139.     r) rolldir="$OPTARG" ;;
  140.     C) forceclean=1 ;;
  141.     d) datum=1 ;;
  142.     t) touch=1 ;;
  143.     j) COMPRESS="bzip2 -9f" ; DOT_Z=".bz2" ;;
  144.     l) COMPRESS="" ;;
  145.     p) preserve=1 ;;
  146.     n) rotateifempty="no" ;;
  147.     q) quiet=1 ;;
  148.     h) usage; exit 0 ;;
  149.     *) usage; exit 1 ;;
  150.     esac
  151. done
  152.  
  153. shift $(($OPTIND - 1))
  154.  
  155. if [ "$count" -lt 2 ]; then
  156.     echo "$prog: count must be at least 2" 1>&2
  157.     exit 2
  158. fi
  159.  
  160. # cycle thru filenames
  161. while [ $# -gt 0 ]; do
  162.  
  163.     # get the filename
  164.     filename="$1"
  165.     shift
  166.  
  167.     # catch bogus files
  168.     if [ -e "$filename" ] && [ ! -f "$filename" ]; then
  169.         echo "$prog: $filename is not a regular file" 1>&2
  170.         exitcode=3
  171.         continue
  172.     fi
  173.  
  174.     # if not a file or empty, do nothing major
  175.     # (in the Debian version, we rotate even if empty by default)
  176.     if [ ! -s "$filename" ] && [ "$rotateifempty" != "yes" ]; then
  177.         # if -t was given and it does not exist, create it
  178.         if test -n "$touch" && [ ! -f "$filename" ]; then 
  179.             touch -- "$filename"
  180.             if [ "$?" -ne 0 ]; then
  181.                 echo "$prog: could not touch $filename" 1>&2
  182.                 exitcode=4
  183.                 continue
  184.             fi
  185.             fixfile "$filename"
  186.         fi
  187.         continue
  188.     fi
  189.  
  190.      # be sure that the savedir exists and is writable
  191.     # (Debian default: $savedir is . and not ./OLD)
  192.      savedir=`dirname -- "$filename"`
  193.      if [ -z "$savedir" ]; then
  194.          savedir=.
  195.      fi
  196.     savedir="$savedir/$rolldir"
  197.      if [ ! -d "$savedir" ]; then
  198.          mkdir -p -- "$savedir"
  199.          if [ "$?" -ne 0 ]; then
  200.              echo "$prog: could not mkdir $savedir" 1>&2
  201.              exitcode=5
  202.              continue
  203.          fi
  204.          chmod 0755 -- "$savedir"
  205.      fi
  206.      if [ ! -w "$savedir" ]; then
  207.          echo "$prog: directory $savedir is not writable" 1>&2
  208.          exitcode=7
  209.          continue
  210.      fi
  211.  
  212.     # determine our uncompressed file names
  213.     newname=`basename -- "$filename"`
  214.     newname="$savedir/$newname"
  215.  
  216.     # cycle the old compressed log files
  217.     cycle=$(( $count - 1))
  218.     rm -f -- "$newname.$cycle" "$newname.$cycle$DOT_Z"
  219.     while [ $cycle -gt 1 ]; do
  220.         # --cycle
  221.         oldcycle=$cycle
  222.         cycle=$(( $cycle - 1 ))
  223.         # cycle log
  224.         if [ -f "$newname.$cycle$DOT_Z" ]; then
  225.             mv -f -- "$newname.$cycle$DOT_Z" \
  226.                 "$newname.$oldcycle$DOT_Z"
  227.         fi
  228.         if [ -f "$newname.$cycle" ]; then
  229.             # file was not compressed. move it anyway
  230.             mv -f -- "$newname.$cycle" "$newname.$oldcycle"
  231.         fi
  232.     done
  233.  
  234.     # compress the old uncompressed log if needed
  235.     if [ -f "$newname.0" ]; then
  236.         if [ -z "$COMPRESS" ]; then
  237.             newfile="$newname.1"
  238.             mv -- "$newname.0" "$newfile"
  239.         else
  240.             newfile="$newname.1$DOT_Z"
  241. #            $COMPRESS < $newname.0 > $newfile
  242. #            rm -f $newname.0
  243.             $COMPRESS "$newname.0"
  244.             mv -- "$newname.0$DOT_Z" "$newfile"
  245.         fi
  246.         fixfile "$newfile"
  247.     fi
  248.  
  249.     # compress the old uncompressed log if needed
  250.     if test -n "$datum" && test -n "$COMPRESS"; then
  251.         $COMPRESS -- "$newname".[0-9]*[0-9]
  252.     fi
  253.  
  254.     # remove old files if so desired
  255.     if [ -n "$forceclean" ]; then
  256.         cycle=$(( $count - 1))
  257.         if [ -z "$COMPRESS" ]; then
  258.             rm -f -- `ls -t -- $newname.[0-9]* | sed -e 1,${cycle}d`
  259.         else
  260.             rm -f -- `ls -t -- $newname.[0-9]*$DOT_Z | sed -e 1,${cycle}d`
  261.         fi
  262.     fi
  263.  
  264.     # create new file if needed
  265.     if [ -n "$preserve" ]; then
  266.         (umask 077
  267.          touch -- "$filename.new"
  268.          chown --reference="$filename" -- "$filename.new"
  269.          chmod --reference="$filename" -- "$filename.new")
  270.         filenew=1
  271.     elif [ -n "$touch$user$group$mode" ]; then
  272.         touch -- "$filename.new"
  273.         fixfile "$filename.new"
  274.         filenew=1
  275.     fi
  276.  
  277.     # link the file into the file.0 holding place
  278.     if [ -f "$filename" ]; then
  279.         if [ -n "$filenew" ]; then
  280.             if ln -f -- "$filename" "$newname.0"; then
  281.                 mv -- "$filename.new" "$filename"
  282.             else
  283.                 echo "Error hardlinking $filename to $newname.0" >&2
  284.                 exitcode=8
  285.                 continue
  286.             fi
  287.         else
  288.             mv -- "$filename" "$newname.0"
  289.         fi
  290.     fi
  291.     [ ! -f "$newname.0" ] && touch -- "$newname.0"
  292.     fixfile "$newname.0"
  293.     if [ -n "$datum" ]; then
  294.         mv -- "$newname.0" "$newname.$DATUM"
  295.     fi
  296.  
  297.     # report successful rotation
  298.     test "$quiet" -eq 1 || echo "Rotated \`$filename' at `date`."
  299. done
  300. exit $exitcode
  301.